package com.eshipenet.shipnet.commplanrpc.service;

import com.eshipenet.shipnet.commplan.CommPlan;
import com.eshipenet.shipnet.commplan.FindAllResult;
import com.eshipenet.shipnet.commplan.Page;
import com.eshipenet.shipnet.commplan.Query;
import com.eshipenet.shipnet.commplan.grpc.CommPlanEdge;
import com.eshipenet.shipnet.commplanrpc.util.BuilderUtil;
import com.eshipenet.shipnet.commplanrpc.util.FormatSql;
import com.eshipenet.shipnet.commplanrpc.util.PageUtil;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.cache.query.FieldsQueryCursor;
import org.apache.ignite.cache.query.QueryCursor;
import org.apache.ignite.cache.query.SqlFieldsQuery;
import org.apache.ignite.cache.query.SqlQuery;
import org.apache.ignite.services.ServiceContext;
import org.json4s.JsonAST;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import scala.Option;
import squirrel.JSONQuery;

import javax.cache.Cache;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class CommPlanServiceImp implements CommPlanService {
  private Logger logger = LoggerFactory.getLogger("CommPlanServiceImp");
  private IgniteCache<String, CommPlan> cache ;
  public CommPlanServiceImp(IgniteCache<String, CommPlan> cache) {
    this.cache = cache;
  }

  @Override
  public FindAllResult findAll(JSONQuery jsonQuery, int limit, int offset) {
    Query query = FormatSql.getFormatSql(jsonQuery);
    SqlQuery<String, CommPlan> sql = new SqlQuery<>(CommPlan.class, query.getSql());
    sql.setArgs(FormatSql.sqlValueToObject(query.getWhere()));
    logger.info("query CommPlan list sql  {}",sql);
    QueryCursor<Cache.Entry<String, CommPlan>> cursor = cache.query(sql);
    Iterator<Cache.Entry<String, CommPlan>> iterator = cursor.iterator();

    List<CommPlanEdge> list = new ArrayList<>();
    //查询数量
    JSONQuery countJsonQuery = JSONQuery.apply(jsonQuery.from(),
                                               jsonQuery.where(),
                                               Option.apply(new JsonAST.JString("count(*) as count")),
                                               jsonQuery.includes(),
                                               jsonQuery.offset(),
                                               jsonQuery.limit());

    Query countQuery = FormatSql.getFormatSql(countJsonQuery);
    SqlFieldsQuery sqlFieldsQuery = new SqlFieldsQuery(countQuery.getSql());
    sqlFieldsQuery.setArgs(FormatSql.sqlValueToObject(countQuery.getWhere()));
    logger.info("query CommPlan count sql  {}",sqlFieldsQuery);
    int totalCount = 0;
    try (FieldsQueryCursor<List<?>> cursor1 = cache.query(sqlFieldsQuery)) {
      for (List<?> row : cursor1) {
        totalCount = Integer.parseInt(row.get(0).toString());
      }

    }

    if(totalCount<1){
      return  new FindAllResult<>(list,totalCount,null,null,false,false);

    }

    //分页工具
    Page page = PageUtil.page(limit, totalCount, offset);
    //起点数据
    int start = page.getStartIndex();
    //结点数据
    int end = page.getEndIndex();
    //计数器
    int times = 0;

    while (iterator.hasNext()) {
      Cache.Entry<String, CommPlan> p = iterator.next();
      if (p != null) {

        if (list.size() < limit) {
          if (times >= start && times < end) {
            CommPlanEdge CommPlanEdge = BuilderUtil.commPlanEdgeBuilder(p);
            list.add(CommPlanEdge);
          }
        } else {
          break;
        }
      }
      times++;
    }

    return  new FindAllResult<>(list,
                                totalCount,
                                list.get(0).getNode().getId(),
                                list.get(list.size()-1).getNode().getId(),
                                page.isHasNextPage(),
                                page.isHasPreviousPage());
  }


  @Override
  public CommPlan createOne(String id,CommPlan CommPlan) {

    cache.put(id,CommPlan);
    CommPlan = cache.get(id);
    return CommPlan;
  }

  @Override
  public CommPlan updateOne(String id,CommPlan commPlan) {

    CommPlan old =  cache.get(id);

    commPlan = new CommPlan(
      commPlan.getName(),
      commPlan.getDescription(),
      commPlan.getKind(),
      commPlan.getAvatar(),
      commPlan.getQuotaData(),
      commPlan.getQuotaFreq(),
      commPlan.getInfo(),
      old.getCreatedAt(),
      commPlan.getUpdatedAt(),
      commPlan.getStatus()
    );

    cache.put(id, commPlan);

    return commPlan;
  }

  @Override
  public CommPlan deleteOne(String id) {

    CommPlan old =  cache.get(id);

    CommPlan commPlan = new CommPlan(
      old.getName(),
      old.getDescription(),
      old.getKind(),
      old.getAvatar(),
      old.getQuotaData(),
      old.getQuotaFreq(),
      old.getInfo(),
      old.getCreatedAt(),
      old.getUpdatedAt(),
      old.getStatus()
    );

    cache.remove(id);
    return commPlan;
  }

  @Override
  public void cancel(ServiceContext ctx) {

  }

  @Override
  public void init(ServiceContext ctx) throws Exception {

  }

  @Override
  public void execute(ServiceContext ctx) throws Exception {

  }
}
